﻿using DevExpress.CodeParser;
using DevExpress.Data;
using Newtonsoft.Json.Linq;
using System.Collections.Frozen;
using Volo.Abp.Domain.Repositories;
using YAPACS.BusinessObjects.Managements.Exams;


namespace YAPACS.RisServer.Services.ExtendCells;

/// <summary>
/// 控件单元格
/// </summary>
public class ControlCell : Cell
{
    private string _key;

    /// <summary>
    /// key    /// </summary>
    public string Key
    {
        get => _key;
        set => _key = value;
    }

    /// <summary>
    /// 空间备注
    /// </summary>
    public string Tag
    {
        get; set;
    }


    /// <summary>
    /// tabIndex
    /// </summary>
    public int TabIndex
    {
        get; set;
    } = 0;

    /// <summary>
    /// 元数据
    /// </summary>
    public ExamDataElement dataElement { get; set; }

    /// <summary>
    /// 值类型(依据检查数据元类型划分)  默认是String
    /// </summary>
    public DataElementValueType CellType { get; set; } = DataElementValueType.String;

    /// <summary>
    /// 构造
    /// </summary>
    /// <param name="key"></param>
    /// <param name="tabIndex"></param>
    public ControlCell(string key, ExamDataElement examDataElement, double width, string tag, int tableIndex)
    {
        Key = key;


        originalWidth = width;
        Tag = tag;
        TabIndex = tableIndex;
        WidthCoculate();
        HeightCoculate();

        Style ??= [];
        Style.Add("position", "relative");
        SetTabIndex();
        if (examDataElement == null)
        {
            SetBodyNoDataElement();
        }
        else
        {
            dataElement = examDataElement;
            CellType = dataElement.ValueType;
            SetBody();
        }
    }

    /// <summary>
    /// 设置储存tabIndex的类名
    /// </summary>
    public void SetTabIndex()
    {
        if (TabIndex != 0)
        {
            this.ClassName = "input-item tabindex-" + TabIndex;
        }
        else
        {
            this.ClassName = "input-item";
        }
    }

    /// <summary>
    /// 有元数据
    /// </summary>
    /// <param name="key"></param>
    public virtual void SetBody()
    {
        Body = new JObject
        {
            { "name", "report.reportExtending." + Key },
            { "id", Guid.NewGuid().ToString() },
            { "disabledOn","!this.report.isEditing"}
        };
        if (!string.IsNullOrEmpty(Key))
        {
            switch (CellType)
            {
                case DataElementValueType.Boolean:
                    Body.Add("type", "checkbox");
                    break;

                case DataElementValueType.Integer:
                    Body.Add("type", "input-number");
                    Body.Add("mode", "normal");
                    Body.Add("validateOnChange", true);
                    AddRemark(Tag);
                    break;

                case DataElementValueType.Enum:

                    Body.Add("type", "select");
                    if (dataElement.IsMultiValue)
                    {
                        Body.Add("multiple", true);
                    }
                    else
                    {
                        Body.Add("multiple", false);
                    }

                    Body.Add("mode", "normal");
                    Body.Add("joinValues", false);
                    JArray options = [];
                    if (!string.IsNullOrEmpty(dataElement.ValueRange))
                    {
                        foreach (string enumValue in dataElement.ValueRange.Split(','))
                        {
                            JObject option = new JObject();
                            option.Add("label", enumValue);
                            option.Add("value", enumValue);
                            options.Add(option);
                        }
                    }

                    Body.Add("options", options);
                    AddRemark(Tag);
                    break;

                case DataElementValueType.Date:
                    Body.Add("type", "input-date");
                    Body.Add("mode", "normal");
                    Body.Add("valueFormat", "YYYY年MM月DD日");

                    break;

                case DataElementValueType.Float:
                    Body.Add("type", "input-number");
                    Body.Add("mode", "normal");
                    Body.Add("validateOnChange", true);

                    Body.Add("precision", 2);
                    AddRemark(Tag);

                    break;

                case DataElementValueType.String:
                    Body.Add("type", "input-text");
                    if (!string.IsNullOrEmpty(dataElement.ValueRange))
                    {
                        JArray optionItems = new JArray();
                        string[] items = dataElement.ValueRange.Split(',');
                        foreach (var item in items)
                        {
                            JObject optionItem = new JObject
                            {
                                        {"label",item },
                                        { "value",item}
                             };
                            optionItems.Add(optionItem);
                        }
                        Body.Add("options", optionItems);
                        if (dataElement.IsMultiValue)
                        {
                            Body.Add("multiple", true);
                        }
                        else
                        {
                            Body.Add("multiple", false);
                        }
                    }
                    Body.Add("mode", "normal");
                    AddRemark(Tag);
                    break;

                case DataElementValueType.Time:
                    Body.Add("type", "input-text");
                    Body.Add("mode", "normal");
                    AddRemark(Tag);
                    break;

                default:
                    break;
            }
        }
    }

    /// <summary>
    /// 无数据元
    /// </summary>
    public virtual void SetBodyNoDataElement()
    {
        Body = new JObject
        {
            { "type","input-text"},
            { "mode","normal"},
            { "name", "report.reportExtending." + Key },
            { "id", Guid.NewGuid().ToString() },
            { "disabledOn","!this.report.isEditing"}
        };
        AddRemark(Tag);
    }


    /// <summary>
    /// 添加提示
    /// </summary>
    /// <param name="tag"></param>
    public void AddRemark(string tag)
    {
        // 控件提示
        JObject remark = new()
        {
            { "icon", "fa fa-question-circle" }
        };
        JArray trigger = ["hover"];
        remark.Add("trigger", trigger);
        remark.Add("className", "Remark--warning");
        remark.Add("placement", "top");
        remark.Add("title", Key);
        List<string> referenceArray = []; //参考值列表
        if (dataElement != null)
        {
            int number = 1;
            foreach (var item in dataElement.ReferenceValues)
            {
                string referenceValue = "";
                referenceValue += ("&nbsp;&nbsp;" + number + "、 参考值：" + item.ReferenceValue);
                if (!string.IsNullOrEmpty(item.PanicValue))
                {
                    referenceValue += (", 危急值：" + item.PanicValue);
                }
                if (item.MaxAge != null)
                {
                    referenceValue += (", 最大年龄：" + item.MaxAge.Value.ToString());
                }
                if (item.MinAge != null)
                {
                    referenceValue += (", 最小年龄：" + item.MinAge.Value.ToString());
                }
                referenceValue += "<br/>";
                referenceArray.Add(referenceValue);
                number++;
            }
        }

        string refernceValueStr = "";
        string description = "";
        string minmax = "";
        if (dataElement != null)
        {
            if (dataElement.ReferenceValues.Count > 0)
            {
                refernceValueStr = "<b>参考值:</b> <br/>" + string.Join("\n\r", referenceArray);
            }



            if (!string.IsNullOrEmpty(dataElement.Description))
            {
                description = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" + dataElement.Description + "<br/>"; //"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;";
            }


        }

        if (!string.IsNullOrEmpty(tag))
        {
            description += (tag + "<br/>");
        }

        if (dataElement != null && !string.IsNullOrEmpty(dataElement.ValueRange))
        {
            string[] valueLimit = dataElement.ValueRange.Split(',');
            if (valueLimit.Length == 2)
            {
                minmax = "<b>最大值：</b>&nbsp;" + valueLimit[0] + "<br/> <b>最小值：</b> &nbsp;" + valueLimit[1] + "<br/>";
            }
        }

        string content = description + minmax + refernceValueStr;

        remark.Add("content", content);
        Body.Add("remark", remark);
    }
}
